/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include<ncurses.h>
#include <stdlib.h>


#define BAUDRATE B57600
#define SERPORT "/dev/ttyUSB0"

void error(const char *msg)
{
	perror(msg);
	exit(1);
}

/*
 * 'open_port()' - Open serial port 1.
 *
 * Returns the file descriptor on success or -1 on error.
 */

/// Global variable
int fd; /* File descriptor for the port */

int open_port(void)
{
        fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);

        if (fd == -1)
        {
                /* Could not open the port. */
                perror(" open_port: Unable to open /dev/ttyUSB0 - ");
                printf(" Error with opening the port ! \n");
        }
        else
        {
                fcntl(fd, F_SETFL, 0);
                printf(" The port is opened! \n");
        }

        return (fd);
}


int options(void)
{
        // Read the configureation of the port
          struct termios options;

        /* SEt Baud Rate */

          cfsetispeed( &options, B57600 );
          cfsetospeed( &options, B57600 );
          printf(" Baud rate=57600,");

          options.c_cflag &= ~PARENB;
          options.c_cflag &= ~CSIZE;
          options.c_cflag |= CS8;
          printf(" Bits=8, Stop bits=1 , Flowcotrol=disable \n");

          options.c_iflag &= ~(IXON | IXOFF | IXANY);

          tcgetattr( fd, &options );
          return 0;
}  
void SendToCreate( int fd, char *data, int length )
{
        int i;

        for( i=0; i<length; i++ )
        {
                if( write(fd, &data[i], 1) == -1 )
                {
                        printf( "\nUnable to write %s", SERPORT );
                       printf( "\nerrno = %d", errno );
                }
                usleep( 5000 );
        }

}


int main(int argc, char *argv[])
{
	int sockfd, newsockfd, portno;
	socklen_t clilen;
	char buffer[256];
	struct sockaddr_in serv_addr, cli_addr;
	int n;
	int ch;
	char    data[256];
	char S;
	
	initscr();
	raw();
	keypad(stdscr, TRUE);
	noecho();


	if (argc < 2)
	{
		fprintf(stderr,"ERROR, no port provided\n");
		exit(1);
	}

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	
	if (sockfd < 0) 
		error("ERROR opening socket");

	bzero((char *) &serv_addr, sizeof(serv_addr));
	portno = atoi(argv[1]);
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);

	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
		error("ERROR on binding");

	listen(sockfd,5);
	clilen = sizeof(cli_addr);
	newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

	if (newsockfd < 0) 
		error("ERROR on accept");

	bzero(buffer,256);
	n = read(newsockfd,buffer,255);
	
	if (n < 0) error("ERROR reading from socket");
		printf("Here is the message: %s\n",buffer);



	/* Curses Initialisations */
initscr();
raw();
keypad(stdscr, TRUE);
noecho();

options(); 	     
open_port(); /// Open the port
        
printw("================================================================================\nWelcome - Press # to Exit\n        - Or 's' to stop the robot\n        - Or arrows to move with robot\n");

while((ch = getch()) != '#')
{
switch(ch)
{
case KEY_UP: //printw("\nUp Arrow");
			data[0] = 128;
                        data[1] = 131;
                        data[2] = 137;
                        data[3] = 0;
                        data[4] = 200;
                        data[5] = 128;
                        data[6] = 0;
       	                SendToCreate( fd, data, 7 );

break;
case KEY_DOWN: //printw("\nDown Arrow");
			data[0] = 128;
                        data[1] = 131;
                        data[2] = 137;
                        data[3] = 255;
                        data[4] = 56;
                        data[5] = 128;
                        data[6] = 0;
       	                SendToCreate( fd, data, 7 );

break;
case KEY_LEFT: //printw("\nLeft Arrow");
			data[0] = 128;
                        data[1] = 131;
                        data[2] = 137;
                        data[3] = 0;
                        data[4] = 200;
                        data[5] = 0;
                        data[6] = 1;
       	                SendToCreate( fd, data, 7 );

break;
case KEY_RIGHT: //printw("\nRight Arrow");
			data[0] = 128;
                        data[1] = 131;
                        data[2] = 137;
                        data[3] = 0;
                        data[4] = 200;
                        data[5] = 255;
                        data[6] = 255;
       	                SendToCreate( fd, data, 7 );

break;
case 's': // stop the robot
			data[0] = 128;
                        data[1] = 131;
                        data[2] = 137;
                        data[3] = 0;
                        data[4] = 0;
                        data[5] = 128;
                        data[6] = 0;
       	                SendToCreate( fd, data, 7 );

break;
default:
{
printw("\nThe pressed key is ");
attron(A_BOLD);
printw("%c", ch);
attroff(A_BOLD);
}
}
}
printw("\n\nBye Now!\n================================================================================\n");

refresh();
getch();
endwin();
         


	n = write(newsockfd,"I got your message",18);

	if (n < 0) error("ERROR writing to socket");

	close(newsockfd);
	close(sockfd);
	
	return 0; 
}
